#pragma once

#include <vector>
#include <string>

// #include <iostream>
// #include <iomanip>

constexpr auto ROWS = 6;
constexpr auto COLUMNS = 7;

enum class STATE {
    FREE,
    RED,
    YELLOW
};

enum class DIRECTION {
    EAST,
    SOUTHEAST,
    SOUTH,
    SOUTHWEST
};

bool check(STATE data[][COLUMNS], DIRECTION d, int x, int y, int count = 0){
    int yN = y, xN = x;
    switch(d){
        case DIRECTION::EAST:
            ++x;
            break;
        case DIRECTION::SOUTHEAST:
            ++x; ++y;
            break;
        case DIRECTION::SOUTH:
            ++y;
            break;
        case DIRECTION::SOUTHWEST:
            --x;
            ++y;
            break;
    }
    if( x >= 0 &&  x < COLUMNS && y >= 0 && y < ROWS && data[y][x] == data[yN][xN] ){
        return ++count > 2 ? true : check( data, d, x, y, count);
    }

    return false;
}

std::string who_is_winner(std::vector<std::string> pieces_position_list)
{
    STATE data[ROWS][COLUMNS] = {};

    // find winner

    auto winner = [&data]() -> STATE {
        for( auto y = 0; y < ROWS; ++y ){
            for( auto x = 0; x < COLUMNS; ++x ){
                if( data[y][x] != STATE::FREE &&
                    ( check(data, DIRECTION::EAST, x, y) || check(data, DIRECTION::SOUTH, x, y)
                        || check(data, DIRECTION::SOUTHEAST, x, y) || check(data, DIRECTION::SOUTHWEST, x, y) )
                ){
                    return data[y][x];
                }
            }
        }

        return STATE::FREE;
    };

    // process moves

    for( const auto & x : pieces_position_list ){
        auto i = 0;
        while( data[i][x[0] - 65] != STATE::FREE)
            ++i;
        data[i][x[0] - 65] = (x.find("Red") == std::string::npos ? STATE::YELLOW : STATE::RED );
        if( winner() != STATE::FREE )
            break;
    }

    // print field
//     for( auto y = 0; y < ROWS; ++y ){
//         for( auto x = 0 ; x < COLUMNS; ++x ){
//             std::string s = "";
//             if( data[y][x] == STATE::RED )
//                 s = "(RED)";
//             else if( data[y][x] == STATE::YELLOW ){
//                 s = "(ORA)";
//             }
//
//             std::cerr  << static_cast<int>( data[y][x] ) << std::setw(8) << s << " | ";
//         }
//         std::cerr << std::endl;
//     }

    switch( winner() ){
        case STATE::RED: return "Red";
        case STATE::YELLOW: return "Yellow";
        case STATE::FREE:
        default:
            return "Draw";
    }
}
